<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>PodGrab</title>
    {{template "commoncss" .}}
    <style>
      .button-delete {
        color: #d11a2a;
      }
      .podcasts .button {
        padding: 0 15px;
      }
      img {
        display: none;
      }
      /* Larger than tablet */
      @media (min-width: 750px) {
        img {
          display: block;
        }
      }
      [v-cloak] {
        display: none;
      }

      .grid .imageContainer{
        max-height: 160px;
        margin-bottom: 10px;
      }

      .grid .contentContainer, .grid .titleContainer{
        display: none;
      }
      .grid .titleContainer{
        height: 70px;
        
      }

      .grid .titleContainer h5{
        font-size: 2rem;
      }

      .grid .podcasts{

        box-shadow: 0 0 0 0px rgb(0 0 0 / 20%);
      }

      .grid .podcasts:hover{
        box-shadow: #ccc 10px 5px 16px 1px;
        transition:all 0.25s;
        transition-timing-function: ease-in-out;
      }

      .grid .tags{
        font-size: 0.85em;
        padding-bottom: 10px;
        display: inline-block;
      }

      .mobile.tags{
        margin-bottom: 10px;
      }

      .alignRight{
        text-align: right;
      }
      .alignLeft{
        text-align: left;
      }
      .tag-editor{
        position: absolute;
        border:1px solid;
        padding: 10px;
        width: 300px;
        z-index: 1000;
      }

      .tag-editor a.pill{
        margin-right: 5px;
        background: blue;
        border-radius: 5px;
        padding: 2px 5px;
        text-decoration: none;
        display: inline-block;
        margin-bottom: 5px;
      }  

      a.pill i{
        background-color: inherit;
        margin-right: 2px;
      }

      .tag-editor .available a.pill{
        background: green;
      }
      .tag-editor .existing a.pill{
        background: palevioletred;
      }

      .tag-editor>div{
        margin-bottom: 15px;;
      } 

      .list hr{
        margin-top: 0.5rem;
        margin-bottom: 1.5rem;
      }
      .list h3{
        margin-bottom: 0rem;
      }
      .list p{
        margin-bottom: 1rem;
      }
      .list .u-full-width{
        width: 80%;
      }

      .paused{
        opacity: 50%;
      }
    </style>
  </head>
  <body>
    <div class="container">
      {{template "navbar" .}}

   
      <br />

      <div id="app" v-cloak>
        <div class="row">
          <div class="columns six">&nbsp;</div>
          <div class="columns six" :class="isMobile?'alignLeft':'alignRight'">
            <select v-model="sortOrder" name="" id="">
              <option v-for="option in sortOptions" v-bind:value="option.key">
                ${option.label}
              </option>

            </select>

            <select v-model="filterTag" v-if="allTags.length">
              <option value="">All</option>
              <option v-for="option in allTags" v-bind:value="option.ID">
                ${option.Label} (${option.Podcasts.length})
              </option>

            </select>

            <select v-if="!isMobile" v-model="layout" name="" id="">
              <option v-for="option in layoutOptions" v-bind:value="option">
                ${option.capitalize()}
              </option>

            </select>

          </div>

        </div>
        <div class="row" :class="layout">
          <template  v-for="podcastGroup in podcastGroups"  >
            <div class="row">
              <template  v-for="podcast in podcastGroup"  >

         
         
        <div :key="podcast.ID" class="podcasts" :title="podcast.Title"  v-bind:class="{row:layout=='list', two:layout=='grid', columns:layout=='grid'}" v-bind:id="'podcast-'+podcast.ID"  >
          <div class="columns imageContainer" v-bind:class="{two:layout=='list', twelve:layout=='grid'}">
            <a style="text-decoration: none" :href="'/podcasts/'+podcast.ID+'/view'">
            <img
              onerror="onImageError(this)"
              class="u-full-width"
              :src="getPodcastImage(podcast)"
             
              v-bind:alt="podcast.Title"
            />
          </a>
          </div>
          <div class="columns" v-bind:class="{ten:layout=='list', twelve:layout=='grid',paused:podcast.IsPaused}">
            <div class="titleContainer">
            <a style="text-decoration: none" :href="'/podcasts/'+podcast.ID+'/view'">
              <h3 v-if="layout=='list'">${podcast.Title}</h3>
              <h5 v-if="layout=='grid'">${podcast.Title} </h5>
             
              </a>
            </div>
           <div class="contentContainer">
            <p class="useMore">${podcast.Summary}</p></div>

            <div class="row">
              <div class="columns" v-bind:class="{two:layout=='list', twelve:layout=='grid'}">
                
                <span v-if="podcast.LastEpisode" :title="'Last Episode aired on '+getFormattedLastEpisodeDate(podcast)">${getFormattedLastEpisodeDate(podcast)}</span> 
              </div>

              <div
              class="columns"  v-bind:class="{two:layout=='list', twelve:layout=='grid'}"
              :title="getEpisodeCountTooltip(podcast)"
            >
              <template v-if="podcast.DownloadingEpisodesCount">
              (${podcast.DownloadingEpisodesCount})/</template>${podcast.DownloadedEpisodesCount}/${podcast.AllEpisodesCount}
              episodes
            </div>
            <div class="columns" v-bind:class="{four:layout=='list', twelve:layout=='grid'}">
              <tagger :class="isMobile?'mobile':'desktop'" v-bind:podcast="podcast" v-on:getalltags="getAllTags()"></tagger>
              
            </div>
            <div class="columns"   v-bind:class="{four:layout=='list', twelve:layout=='grid'}">
              <button
                class="button button-delete deletePodcast"
                :data-id="podcast.ID"
                title="Delete Podcast and episode files"
              >
                <i class="fas fa-trash"></i>
                   </button>
                  <div :id="'deleteDdl-'+podcast.ID" style="display: none">
              <ul>
                 <li style="list-style: none;">   <button class="button" :data-id="podcast.ID" onclick="deletePodcast(this)" >Delete Files and Podcast</button></li>
                
                  <li style="list-style: none;">  <button class="button" :data-id="podcast.ID" onclick="deletePodcastEpisodes(this)">Delete Files, Keep Podcast</button></li>
                
                    <li style="list-style: none;">  <button class="button" :data-id="podcast.ID" onclick="deleteOnlyPodcast(this)">Keep Files, Delete Podcast</button></li>
                  </ul>
                </div>
              
              <!-- <button
                class="button button-delete"
                title="Delete only episode files"
                @click="deletePodcastEpisodes(podcast.ID)"
              >
                <i class="fas fa-folder-minus"></i>
              </button> -->

              <button
                class="button"
                title="Download all episode files"
                @click="downloadAllEpisodes(podcast.ID)"
              >
                <i class="fas fa-download"></i>
              </button>

              <button
              class="button"
              title="Play all episodes"
              @click="playPodcast(podcast.ID)"
            >
              <i class="fas fa-play"></i>
            </button>

            <button
            class="button"
            title="Add all episodes to existing player playlist"
            v-if="playerExists"
            @click="enquePodcast(podcast.ID)"
          >
            <i class="fas fa-plus"></i>
          </button>
          <button
          class="button"
          title="New episodes for this podcast are not being downloaded automatially. Click to resume download."
          v-if="podcast.IsPaused"
          @click="togglePause(podcast,false)"
        >
          <i style="color: greenyellow;" class="fas fa-dot-circle"></i>
        </button>
        <button
        class="button"
        title="Click to pause automatic downloading for this podcast."
        v-if="!podcast.IsPaused"
        @click="togglePause(podcast,true)"
      >
        <i style="color: red;" class="fas fa-dot-circle"></i>
      </button>
      <button
      class="button"
      title="Click to see details."
      
      @click="showDetails(podcast)"
    >
      <i  class="fas fa-info"></i>
    </button>
            </div>
            </div>
          </div>
        </div>
        <hr v-if="layout=='list'">
     </template>
    </div>
    <br>
      </template>
    </div>

    <template v-if="allPodcasts.length && !podcasts.length">
      <div class="welcome">
        <h5>No results!</h5>
      <p>There doesn't seem to be any podcast for this filter criteria.</p></div>
      </template>
    </template>
     <template v-if="!allPodcasts.length">
      <div class="welcome">
      <h5>Welcome</h5>
      <p>It seems you have just setup Podgrab for the first time.</p>
      <p>
        Before you start adding and downloading podcasts I recommend that you
        give a quick look to the <a href="/settings"><strong>Settings</strong> here</a> so that you can customize the
        downloading behavior of the software as per your needs.
      </p>
      <p>
        <a href="/add">Click here</a> to add
        a new podcast to start downloading.
      </p>
      <p>
        Please feel free to report any issues or request any features on our github page <a target="_blank" href="https://github.com/akhilrex/podgrab">here</a>
      </p>
    </div>
   
  </template>
  <Modal v-model="showDetail">
    <table class="table" v-if="detailPodcast">
      <tr>
        <td>Title</td>
        <td>${detailPodcast.Title}</td>
      </tr>
     
      <tr>
        <td>Author</td>
        <td>${ detailPodcast.Author }</td>
      </tr>
      <tr>
        <td>Original Url</td>
        <td> <a target="_blank" :href="detailPodcast.URL">Link</a></td>
      </tr>

      <tr>
        <td>Summary</td>
        <td style="word-wrap: break-word;">${ detailPodcast.Summary }</td>
      </tr>
      <tr>
        <td>Added On</td>
        <td>${ getFormattedDate(detailPodcast.CreatedAt)}</td>
      </tr>
      <tr>
        <td>Last Episode</td>
        <td>${ getFormattedLastEpisodeDate(detailPodcast)}</td>
      </tr>
      <tr>
        <td>Paused</td>
        <td> ${ detailPodcast.IsPaused?'Yes':'No' }</td>
      </tr>
      <tr>
        <td>Podgrab Feed</td>
        <td> <a target="_blank" :href="'/podcasts/'+detailPodcast.ID+'/rss'">Link</a></td>
      </tr>
    </table>

  </Modal>
 </div>
    </div>
    {{template "scripts"}}
    <script src="/webassets/popper.min.js"></script>
    <script src="/webassets/tippy-bundle.umd.min.js"></script>
    <script src="/webassets/stopword.js"></script>
    <script src="/webassets/modal/vue-modal.umd.min.js"></script>
    <link rel="stylesheet" href="/webassets/modal/vue-modal.css">
 
    <template id="editTags">
      <div class="tags">
        <div @click="editTags" style="cursor: pointer;">
        <i class="fas fa-tags"></i> 
       ${ commaSeparatedTags() }        
      </div>
       <div v-if="editing" class="tag-editor">
         <h5>Tags: ${podcast.Title}</h5>
          <div class="available">
           Add: <a style="cursor: pointer;" href="#"  @click.prevent="addTag(tag.ID, $event);return false;" v-for="tag in availableTags" class="pill"><i class="fa fa-plus-circle"></i>${tag.Label}</a>
         </div>
         <div class="existing" v-if="tags.length">
           Remove: <a style="cursor: pointer;"  @click.prevent="removeTag(tag.ID, $event);return false;" href="#" v-for="tag in tags" class="pill"><i class="fa fa-minus-circle"></i>${tag.Label}</a>
         </div>
         <div class="create">
           <form @submit.prevent="createNewTag" method="post">
           <input type="text" name="newTag" id="" placeholder="Create New Tag" v-model="newTag">
           <input type="submit" value="Add">
          </form>
         </div>
         <button class="button" @click="editing=false">Close</button>
       </div>
       </div>
    </template>
    <script>
      Vue.component('Modal', VueModal)

      Vue.component('tagger',{
        delimiters: ["${", "}"],
        data:function(){
          return {
            newTag:'',
            allTags:[],
            tags:[],
            availableTags:[],
            editing:false,
          }
        },
        template: '#editTags',
        props:['podcast'],
        computed:{
        
        },
        methods:{
          createNewTag(){
            var self=this;
            if(!self.newTag){
              return;
            }
             axios
              .post("/tags",{label:self.newTag})
              .then(function (response) {
                self.tags.push(response.data);
                self.addTag(response.data.ID);
                self.getAllTags();
               
              }).catch(showError);
          },
          setAvailableTags(){
              existingTags= this.tags.map(x=>x.ID);
              this.availableTags= this.allTags.filter(x=>existingTags.indexOf(x.ID)===-1);
              this.$emit('getalltags')
            }
          ,
          commaSeparatedTags(){
            if(!this.tags.length){
              return "";
            }
         
            toReturn= this.tags.map(function(x){return x.Label}).join(", ");
            return toReturn;
          },
          editTags(){
            this.editing=!this.editing;
            if(this.editing){
              this.getAllTags();
            }
          },
          getAllTags(){
            var self=this;
             axios
              .get("/tags")
              .then(function (response) {
                self.allTags=response.data;
                self.setAvailableTags();
              })
          },
        
        addTag(tagId,e){
         

          var self=this;
             axios
              .post("/podcasts/"+this.podcast.ID+"/tags/"+tagId)
              .then(function (response) {
                var i=-1;
                for(i=0;i<self.allTags.length;i++){
                    if(self.allTags[i].ID===tagId){
                      self.tags.push(self.allTags[i]);
                      break;
                    }
                }

                self.setAvailableTags();
              }).catch(showError);
              return false;
        },
        removeTag(tagId,e){
        

          var self=this;
             axios
              .delete("/podcasts/"+this.podcast.ID+"/tags/"+tagId)
              .then(function (response) {
                var i=-1;
                for(i=0;i<self.tags.length;i++){
                    if(self.tags[i].ID===tagId){
                      break;
                    }
                }
                self.tags.splice(i,1)
              
                self.setAvailableTags();
              });
            return false;
        },
      },
        mounted(){
          this.tags=this.podcast.Tags;
        }
      });

    </script>
    <script>
        var app = new Vue({
        delimiters: ["${", "}"],
        el: "#app",
        computed:{
            podcastGroups(){
              var i,j,temparray,chunk = 6;
              var toReturn=[];
                for (i=0,j=this.podcasts.length; i<j; i+=chunk) {
                  toReturn.push(this.podcasts.slice(i,i+chunk));
                    // do whatever
                }
                return toReturn
            }
        },
        created(){
          this.podcasts=this.allPodcasts;
          const self=this;
         this.socket= getWebsocketConnection(function(event){
              const message= getWebsocketMessage("Register","Home")
                  self.socket.send(message);
            },function(x){
              const msg= JSON.parse(x.data)
              if(msg.messageType=="NoPlayer"){
                self.playerExists=false;
              }
              if(msg.messageType=="PlayerExists"){
                self.playerExists=true;
              }
            });

        },
        methods:{
          showDetails(podcast){
            this.detailPodcast=podcast;
            this.showDetail=true;
          },
          getPodcastImage(item){
            return "/podcasts/"+item.ID+"/image"
          },
          removePodcast(id) {      
           const index= this.podcasts.findIndex(x=>x.ID===id);
           this.podcasts.splice(index,1);       
          },
          enquePodcast(id){
            if(!this.playerExists){
              return
            }
            this.socket.send(getWebsocketMessage("Enqueue",`{"podcastId":"${id}"}`))
          },
          togglePause(item,isPaused){
            var self=this;
            var url= isPaused?`/podcasts/${item.ID}/pause`:`/podcasts/${item.ID}/unpause`;
            axios
              .get(url)
              .then(function (response) {
                 item.IsPaused=isPaused;

              })
              .catch(function (error) {
                if (error.response && error.response.data && error.response.data.message) {
                  Vue.toasted.show(error.response.data.message, {
                    theme: "bubble",
                    type: "error",
                    position: "top-right",
                    duration: 5000,
                  });
                }
              })
              
          },
          filterPodcasts(){
            if(this.filterTag===""){
              this.podcasts=this.allPodcasts;
            }else{
              var filtered=[];
              for (var podast of this.allPodcasts) {
                  for(var tag of podast.Tags){
                    if(tag.ID===this.filterTag){
                      filtered.push(podast);
                      break;
                    }
                  }
              }
              this.podcasts=filtered;
          }
            this.sortPodcasts();
          },
          sortPodcasts(order){
              var compareFunction;
              switch(order){
                case "dateAdded-asc":compareFunction=(a,b)=>Date.parse(a.CreatedAt)-Date.parse(b.CreatedAt);break;
                case "dateAdded-desc":compareFunction=(a,b)=>Date.parse(b.CreatedAt)-Date.parse(a.CreatedAt);break;
                case "lastEpisode-asc":compareFunction=(a,b)=>Date.parse(a.LastEpisode)-Date.parse(b.LastEpisode);break;
                case "lastEpisode-desc":compareFunction=(a,b)=>Date.parse(b.LastEpisode)-Date.parse(a.LastEpisode);break;
                case "episodesCount-asc":compareFunction=(a,b)=>a.AllEpisodesCount-b.AllEpisodesCount;break;
                case "episodesCount-desc":compareFunction=(a,b)=>b.AllEpisodesCount-a.AllEpisodesCount;break;
                case "name-asc":compareFunction=(a,b)=>{
                               var nameAArr = sw.removeStopwords(a.Title.split(' ')) ;
                              var nameBArr = sw.removeStopwords(b.Title.split(' '));

                              nameA= nameAArr.length?nameAArr[0].toUpperCase():"";
                              nameB= nameBArr.length?nameBArr[0].toUpperCase():"";
                              if (nameA < nameB) {
                                return -1;
                              }
                              if (nameA > nameB) {
                                return 1;
                              }

                              // names must be equal
                              return 0;
                };break;
                case "name-desc":compareFunction=(a,b)=>{
                             var nameAArr = sw.removeStopwords(b.Title.split(' ')) ;
                              var nameBArr = sw.removeStopwords(a.Title.split(' '));

                              nameA= nameAArr.length?nameAArr[0].toUpperCase():"";
                              nameB= nameBArr.length?nameBArr[0].toUpperCase():"";
                              if (nameA < nameB) {
                                return -1;
                              }
                              if (nameA > nameB) {
                                return 1;
                              }

                              // names must be equal
                              return 0;
                };break;
               
              }
              this.podcasts.sort(compareFunction)
          },

          getReadableSize(bytes){
            if(bytes<1024){
              return `${bytes} bytes`;
            }
            bytes=bytes/1024
            if(bytes<1024){
              return `${bytes.toFixed(2)} KB`;
            }
            bytes=bytes/1024
            if(bytes<1024){
              return `${bytes.toFixed(2)} MB`;
            }
            bytes=bytes/1024
            if(bytes<1024){
              return `${bytes.toFixed(2)} GB`;
            }
            bytes=bytes/1024
            return `${bytes.toFixed(2)} TB`;
          
          },
          getEpisodeCountTooltip(podcast){
            var title=`${podcast.DownloadedEpisodesCount} episodes (${this.getReadableSize(podcast.DownloadedEpisodesSize)}) downloaded out of total ${podcast.AllEpisodesCount} episodes (${this.getReadableSize(podcast.AllEpisodesSize)})`
            if(podcast.DownloadingEpisodesCount){
                    title+= '\n'+podcast.DownloadingEpisodesCount+' episodes ('+ this.getReadableSize(podcast.DownloadingEpisodesSize)+') in the queue.'
            
            }
                return title
          },
          getFormattedLastEpisodeDate(podcast){
           const options={month:"short", day:"numeric", year:"numeric"}
           //todo: this is a really dirty hack which needs to be fixed when we work on the episode page
           var dt=new Date(Date.parse(podcast.LastEpisode.substr(0,10)));
           return dt.toDateString()
          },
          getFormattedDate(date){
           const options={month:"short", day:"numeric", year:"numeric"}
           //todo: this is a really dirty hack which needs to be fixed when we work on the episode page
           var dt=new Date(Date.parse(date.substr(0,10)));
           return dt.toDateString()
          },
          downloadAllEpisodes(id) { downloadAllEpisodes(id);},
          deletePodcast(id){ deletePodcast(id,()=>{
           
              const index= this.podcasts.findIndex(x=>x.ID===id);
              this.podcasts.splice(index,1);
          });},
          deletePodcastEpisodes(id){ deletePodcastEpisodes(id)},
          playPodcast(id){openPlayer("",id)},
          getAllTags(){
            var self=this;
             axios
              .get("/tags")
              .then(function (response) {
                self.allTags=response.data;
              })
          },
        },
        mounted(){
          if(localStorage && localStorage.sortOrder){
            this.sortOrder=localStorage.sortOrder;
            this.sortPodcasts(this.sortOrder);
          }
          if(localStorage && localStorage.layout){
            this.layout=localStorage.layout;
          }else{
              this.layout='list';
          }

          if(localStorage && localStorage.filterTag){
            this.filterTag=localStorage.filterTag;
          }else{
              this.filterTag='';
          }

          if (screen.width <= 760) {
                this.isMobile= true
              } else {
                this.isMobile= false
              }
          
          if (screen.width <= 760) {
            this.layout='list'
          }
          this.getAllTags();
          
          this.$nextTick(function () {

          checkUseMore();
          tippy(".deletePodcast",{
            allowHTML: true,
            content(reference) {
             
              const id = reference.getAttribute('data-id');
            
              const template = document.getElementById('deleteDdl-'+id);
            
              return template.innerHTML;
          },
          trigger:'click',
          interactive: true
          })
        })
        },
        watch:{
          sortOrder(newOrder,oldOrder){
            if(newOrder===oldOrder){
              return;
            }
            if(localStorage){
              localStorage.sortOrder=newOrder
            }
            this.sortPodcasts(newOrder);
          },
          filterTag(newTag,oldTag){
            
            if(newTag===oldTag){
              return;
            }
            if(localStorage){
              localStorage.filterTag=newTag
            }
            this.filterPodcasts();
          },
          layout(newLayout,oldLayout){
            if(newLayout===oldLayout){
              return;
            }
            if(localStorage){
              localStorage.layout=newLayout
            }
          },
        },
        data: {
          socket:null,
          detailPodcast:null,
          showDetail:false,
          playerExists:false,
          isMobile:false,
          layoutOptions:["list","grid"],
          layout:"grid",
          sortOrder:"dateAdded-asc",
          allTags:[],
          filterTag:'',
            sortOptions:[
              {
                key:"name-asc",
                label:"Name (A-Z)"
              },
              {
                key:"name-desc",
                label:"Name (Z-A)"
              },
              {
                key:"lastEpisode-asc",
                label:"Latest Episode (Old First)"
              },
              {
                key:"lastEpisode-desc",
                label:"Latest Episode (New First)"
              },
              
              {
                key:"dateAdded-asc",
                label:"Date Added (Old First)"
              },
              {
                key:"dateAdded-desc",
                label:"Date Added (New First)"
              },
              {
                key:"episodesCount-asc",
                label:"Episodes Count (Asc)"
              },
              {
                key:"episodesCount-desc",
                label:"Episodes Count (Desc)"
              },
            ],
            podcasts:[],
            {{ $len := len .podcasts}}
            allPodcasts: {{if gt $len 0}} {{ .podcasts }} {{else}} [] {{end}},
        }})
     
    </script>
    
  </body>
</html>
